package task

import (
	"bytes"
	"encoding/json"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"io/ioutil"
	"net/http"
	"time"

	lmodel "payspace/models"
)

const url = "https://relay1.loopring.io/rpc/v2/"

// update supported token
func updateTokens() {

	for {
		params := make(map[string]string)

		p := make([]interface{}, 0)
		p = append(p, params)

		requestData := make(map[string]interface{})
		requestData["Jsonrpc"] = "2.0"
		requestData["Method"] = "loopring_getSupportedTokens"
		requestData["Params"] = p
		requestData["Id"] = 64

		jsonData, err := json.Marshal(requestData) // 序列化成json

		req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
		req.Header.Set("Content-Type", "application/json")

		client := &http.Client{}

	RequestUpdateTokens:
		resp, err := client.Do(req)
		if err != nil {
			// handle error
			logs.Error("call api failed.", err)
			time.Sleep(5 * time.Second)
			goto RequestUpdateTokens
		}

		result := make(map[string]interface{})
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			logs.Error("parse response failed:", err)
			time.Sleep(5 * time.Second)
			goto RequestUpdateTokens
		}

		err = json.Unmarshal(body, &result)
		if err != nil {
			logs.Error("parse response failed:", err)
			time.Sleep(5 * time.Second)
			goto RequestUpdateTokens
		}

		resp.Body.Close()

		// update database
		tokens := result["result"]
		if tokens == nil {
			logs.Error("parse response failed:", err)
			time.Sleep(5 * time.Second)
			continue
		}

		for _, token := range tokens.([]interface{}) {
			token := token.(map[string]interface{})

			var supportedToken lmodel.Token
			supportedToken.Symbol = token["symbol"].(string)
			supportedToken.Protocol = token["protocol"].(string)
			supportedToken.Source = token["source"].(string)
			supportedToken.Deny = token["deny"].(bool)
			supportedToken.Decimals = token["decimals"].(float64)
			supportedToken.IsMarket = token["isMarket"].(bool)

			o := orm.NewOrm()
			// 判断数据是否存在
			t := lmodel.Token{Symbol: token["symbol"].(string)}
			err = o.Read(&t, "Symbol")
			if err == nil {
				// 更新数据
				if _, err := o.Update(&supportedToken); err != nil {
					logs.Error("Update supported token failed: ", err)
				}
			} else {
				// 新增数据
				if _, err := o.Insert(&supportedToken); err != nil {
					logs.Error("Add supported token failed: ", err)
				}
			}

		}
		logs.Info("supported tokens updated.")
		time.Sleep(24 * time.Hour)
	}
}

func Init() {

	go updateTokens()
	go updatePrice()
	go updateStatus()
	go updateTransaction()
}
